package com.cloudspace.yunloan.update;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.cloudspace.yunloan.BuildConfig;
import com.cloudspace.yunloan.R;
import com.cloudspace.yunloan.activity.YunloanActivity;
import com.cloudspace.yunloan.ext.aq.AQUtility;
import com.cloudspace.yunloan.global.Res;
import com.cloudspace.yunloan.log.APPLog;
import com.cloudspace.yunloan.network.JsonCallBack;
import com.cloudspace.yunloan.network.api.API;
import com.cloudspace.yunloan.utils.FileUtil;
import com.cloudspace.yunloan.utils.MMAlert;
import com.cloudspace.yunloan.utils.MyDialog;
import com.cloudspace.yunloan.utils.ObjUtil;
import com.cloudspace.yunloan.utils.ToastMaker;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import okhttp3.Call;
import okhttp3.Response;


public class UpdateAgent {
    private class DownloadTask extends AsyncTask<String, Integer, String> {
        private Context context;
        private PowerManager.WakeLock mWakeLock;

        public DownloadTask(Context context) {
            this.context = context;
        }

        @Override
        protected String doInBackground(String... sUrl) {
            InputStream input = null;
            OutputStream output = null;
            HttpURLConnection connection = null;
            try {
                URL url = new URL(sUrl[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                // expect HTTP 200 OK, so we don't mistakenly save error report
                // instead of the file
                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    return "Server returned HTTP " + connection.getResponseCode()
                            + " " + connection.getResponseMessage();
                }
                // this will be useful to display download percentage
                // might be -1: server did not report the length
                int fileLength = connection.getContentLength();
                // download the file
                input = connection.getInputStream();
                output = new FileOutputStream(FileUtil.getLocalFileDownloadPath() + "/" + "yunloan.apk");
                byte data[] = new byte[4096];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    // allow canceling with back button
                    if (isCancelled()) {
                        input.close();
                        return null;
                    }
                    total += count;
                    // publishing the progress....
                    if (fileLength > 0) // only if total length is known
                        publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }
            } catch (Exception e) {
                return e.toString();
            } finally {
                try {
                    if (output != null)
                        output.close();
                    if (input != null)
                        input.close();
                } catch (IOException ignored) {
                }
                if (connection != null)
                    connection.disconnect();
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // take CPU lock to prevent CPU from going off if the user
            // presses the power button during download
            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    getClass().getName());
            mWakeLock.acquire();
            showDownloadProgress(mActivity);
        }


        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            // if we get here, length is known, now set indeterminate to false
            APPLog.zxhLog(TAG, "progress:" + progress[0] + ", downloadProgress:" + downloadProgress);
            if (progress[0] > downloadProgress + 5 || progress[0] == 100){
                downloadProgress = progress[0];
                updateDownloadProgress(progress[0]);
            }

        }
        @Override
        protected void onPostExecute(String result) {
            mWakeLock.release();
            if (result != null) {
                downloadFail();
            }
            else {
                APPLog.zxhLog("download success");
                downloadSuccess();
            }
        }
    }

    public static final int DOWNLOAD_APK_NOTIFY_ID = 12934445;

    private static final String TAG = UpdateAgent.class.getSimpleName();

    private MyDialog mergeProgressDialog;
    private ProgressBar mProgressBar = null;

    private TextView mProgressRate;

    private YunloanActivity mActivity;
    private UpdateInfo updateInfo;

    private boolean fromMainactivity;

    private long downloadProgress = 0;

    public UpdateAgent(YunloanActivity activity){
        this.mActivity = activity;
    }

    public void getUpdateinfo(boolean fromMainactivity) {
        this.fromMainactivity = fromMainactivity;
        API.getInstance().getUserApi().updateapp(this, new JsonCallBack<UpdateInfoResult>() {
            @Override
            public void onSuccess(UpdateInfoResult updateInfoResult,
                                  Call call, Response response) {
                if (mActivity != null) {
                    mActivity.hideLoadingDialog();
                }

                if (updateInfoResult != null){
                    updateInfo = updateInfoResult.data;
                }

                showUpdateDialog();
            }

            @Override
            public void onError(Call call, Response response, Exception e) {
                super.onError(call, response, e);

                if (mActivity != null) {
                    mActivity.hideLoadingDialog();
                }
            }
        });
    }

    private MyDialog updateDialog = null;

    private void showUpdateDialog() {
        if (updateInfo == null){
            return;
        }

        String serverVersionName = updateInfo.version;
        APPLog.zxhLog(TAG, "must:" + updateInfo.must);

        if (!TextUtils.equals(BuildConfig.VERSION_NAME, serverVersionName)) {
            if (updateInfo.must){
                updateDialog =  MMAlert.showAlert(mActivity, mActivity.getString(R.string.must_update_tip),
                        mActivity.getResources().getString(R.string.update_title),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                startDownloadApk();
                            }
                        });

                if (updateDialog != null){
                    updateDialog.setCancelable(false);
                }
            }else{
                String mUpdateInfoStr = mActivity.getString(R.string.update_message);

                updateDialog =  MMAlert.showAlert(mActivity, mUpdateInfoStr,
                        mActivity.getResources().getString(R.string.update_title),
                        null, mActivity.getResources().getString(R.string.update_now),
                        mActivity.getResources().getString(R.string.update_next_time), true, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                startDownloadApk();
                            }
                        }, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.dismiss();
                            }
                        });
            }



        }
    }

    private void updateDownloadProgress(int progress) {
        APPLog.zxhLog(TAG + " updateDownloadProgress:" + progress);

        if (progress < 0) {
            progress = 0;
        }

        if (progress > 100) {
            progress = 100;
        }

        final int downloadProgress = progress;

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mProgressBar != null) {
                    mProgressBar.setProgress(downloadProgress);
                    displayDownloadProgress(downloadProgress);
                }
            }
        });
    }

    private void startDownloadApk() {
        if (ObjUtil.isEmpty(updateInfo) || ObjUtil.isEmpty(updateInfo.url)){
            return;
        }

        String path = FileUtil.getLocalFileDownloadPath() + "/" + "yunloan.apk";
        APPLog.zxhLog("download file:" + path);

        downloadProgress = 0;

        AQUtility.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (downloadProgress == 0){
                    downloadFail();
                }
            }
        }, 10*1000);

        showDownloadProgress(mActivity);

        final DownloadTask downloadTask = new DownloadTask(mActivity);
        downloadTask.execute(updateInfo.url);
    }

    private void downloadFail() {
        ToastMaker.showToastShort(R.string.download_fail);
        dismissDownloadDialog();
    }

    private void dismissUpdateDialog() {
        if (updateDialog != null){
            updateDialog.dismiss();
            updateDialog = null;
        }
    }

    public void displayDownloadProgress(int rate) {
        if (rate > 0.5 && !mActivity.isFinishing()) {
            try {
                mProgressRate.setText(rate + "%");
                mProgressBar.setProgress(rate);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public void install(Context context) {
        Intent i = new Intent(Intent.ACTION_VIEW);

        String filePath = FileUtil.getLocalFileDownloadPath() + "/" + "yunloan.apk";

        try {
            i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        } catch (Exception e) {
            APPLog.zxhLog(TAG + Log.getStackTraceString(e));
        }

    }

    private void downloadSuccess() {
        updateDownloadProgress(100);

        dismissDownloadDialog();

        install(mActivity);
    }

    private void dismissDownloadDialog() {
        if (mergeProgressDialog != null) {
            mergeProgressDialog.dismiss();
            mergeProgressDialog = null;
        }
    }


    public void showDownloadProgress(final Activity mActivity) {
        if (mActivity.isFinishing()) {
            return;
        }

        if (null == mergeProgressDialog || !mergeProgressDialog.isShowing()) {
            View mPopView = LayoutInflater.from(mActivity).inflate(R.layout.upload_popup_box, null);
            mProgressBar = (ProgressBar) mPopView.findViewById(R.id.upload_progress);
            mProgressBar.setProgress(0);
            mProgressRate = (TextView) mPopView.findViewById(R.id.progress_text);

            mergeProgressDialog = MMAlert.showAlert(mActivity, mActivity.getString(R.string.update_download), mPopView,
                    null, null);

        }
        if (!mergeProgressDialog.isShowing()) {
            mergeProgressDialog.show();
        }

        updateDownloadProgress(1);
    }
}
